<template>
  <div class="home">
    <h1>{{ a }}</h1>
    <h2> {{ ht }}</h2>
    <h1> {{ ft }}</h1>
    <h1> {{state.title}}</h1>
    <h1>{{stateCopy.title}}</h1>
    <button @click="fn1">我是一个按钮</button>
    <button @click="fn3">我是第二个按钮</button>
    <button @click="fn4">我是第三个按钮</button>
    <kfc :a1="ht" a2="2222" @eee="fn2">
      9999999
    </kfc>
  </div>
</template>
<script>
import {
  ref, watch, computed, onMounted, reactive, readonly, watchEffect,
} from 'vue';
import kfc from '../components/kfc.vue';

export default {
  name: 'Home',
  components: {
    kfc,
  },
  data () {
    return {
      a: 'himan',
    };
  },
  methods: {
    fn2 () {
      console.log('我是被内部emit触发的函数');
    },
  },
  // eslint-disable-next-line no-unused-vars
  setup (props, ctx) {
    //  ref的应用
    //  在setup中return的内容将会在组件内被使用
    //  也可以理解成 如果没有return 将跟组件无关
    const ht = ref(777); // ref函数是用来创建响应式数据函数的第一个参数就是初始值
    // 对于ref创建的响应数据如果我们需要在js部分使用到他的值
    // 需要读取的是它的value属性
    console.log('直接consolelog ht', ht);
    console.log('读取值用value 属性', ht.value);

    // watch的应用
    watch(ht, (nv, ov) => { // 第一个参数是改变之后的值  第二个是改变之前的值
      console.log('ht is changed', nv, ov);
    });
    // 生命周期函数
    //  1 setup函数本身就会在 beforeCreate之前执行
    // created  beforeCreate在setup当中被废弃  没有对应的钩子
    onMounted(() => {
      console.log('在数据加载渲染完成之后执行的函数');
    });
    // computed计算属性
    const ft = computed(() => ht.value * 2);

    // 通过 reactive 来初始化响应数据    reative函数的参数是对象 创建的是一个响应式的数据
    // 跟ref不同的是  reactive 出来的值是可以直接读取而不需要读取 .value属性 也可以直接赋值

    const state = reactive({
      title: '我是一个标题',
      ppp: '我是一个段落',
    });

    // 尝试去用wath来监听state的变化
    watch(state, (nv) => console.log(nv));

    const stateCopy = readonly(state);

    const fn1 = () => {
      // 如果需要修改ht在模板中的值 就需要给value属性赋值
      ht.value = 999;

      //
    };

    const fn3 = () => {
      state.title = '标题又变了';
      //
    };

    // watchEffect函数会返回一个值 这个值是一个函数 执行这个函数可以停止watchEffect监听
    const stop = watchEffect(() => {
      // watchEffect会监听所有在这个函数当中被使用到的响应数据
      // watchEffect不会像watch一样得到 nv（变化后） 和ov（变化前）的参数
      console.log('不过什么变化我都会触发');
      console.log(state.title); // 如果在函数中使用到的相应数据变化 都会触发watchEffect
      console.log(ht.value);
    });

    const fn4 = () => {
      stop();
    };
    return {
      ht,
      fn1,
      ft,
      state,
      fn3,
      fn4,
      stateCopy,
    };
  },
};
</script>
